﻿using System.Diagnostics.Contracts;
using System.Reactive.Disposables;
#if !SILVERLIGHT
using System.Threading;
using System.Threading.Tasks;
#endif

namespace System.Reactive.Concurrency
{
	public static class Scheduler
	{
		public static CurrentThreadScheduler CurrentThread
		{
			get
			{
				Contract.Ensures(Contract.Result<CurrentThreadScheduler>() != null, null, "Contract.Result<CurrentThreadScheduler>() != null");
				return null;
			}
		}

		public static DefaultScheduler Default
		{
			get
			{
				Contract.Ensures(Contract.Result<DefaultScheduler>() != null, null, "Contract.Result<DefaultScheduler>() != null");
				return null;
			}
		}

		public static ImmediateScheduler Immediate
		{
			get
			{
				Contract.Ensures(Contract.Result<ImmediateScheduler>() != null, null, "Contract.Result<ImmediateScheduler>() != null");
				return null;
			}
		}

		public static IScheduler DisableOptimizations(this IScheduler scheduler)
		{
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<IScheduler>() != null, null, "Contract.Result<IScheduler>() != null");
			return null;
		}

		public static IDisposable Schedule(this IScheduler scheduler, Action<Action> action)
		{
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Requires(action != null, null, "action != null");
			Contract.Ensures(Contract.Result<IDisposable>() != null, null, "Contract.Result<IDisposable>() != null");
			return null;
		}

		public static IDisposable Schedule(this IScheduler scheduler, Action action)
		{
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Requires(action != null, null, "action != null");
			Contract.Ensures(Contract.Result<IDisposable>() != null, null, "Contract.Result<IDisposable>() != null");
			return null;
		}

		public static IDisposable Schedule(this IScheduler scheduler, DateTimeOffset dueTime, Action action)
		{
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Requires(action != null, null, "action != null");
			Contract.Ensures(Contract.Result<IDisposable>() != null, null, "Contract.Result<IDisposable>() != null");
			return null;
		}

		public static IDisposable Schedule(this IScheduler scheduler, DateTimeOffset dueTime, Action<Action<DateTimeOffset>> action)
		{
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Requires(action != null, null, "action != null");
			Contract.Ensures(Contract.Result<IDisposable>() != null, null, "Contract.Result<IDisposable>() != null");
			return null;
		}

		public static IDisposable Schedule<TState>(this IScheduler scheduler, TState state, Action<TState, Action<TState>> action)
		{
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Requires(action != null, null, "action != null");
			Contract.Ensures(Contract.Result<IDisposable>() != null, null, "Contract.Result<IDisposable>() != null");
			return null;
		}

		public static IDisposable Schedule(this IScheduler scheduler, TimeSpan dueTime, Action action)
		{
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Requires(action != null, null, "action != null");
			Contract.Ensures(Contract.Result<IDisposable>() != null, null, "Contract.Result<IDisposable>() != null");
			return null;
		}

		public static IDisposable Schedule(this IScheduler scheduler, TimeSpan dueTime, Action<Action<TimeSpan>> action)
		{
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Requires(action != null, null, "action != null");
			Contract.Ensures(Contract.Result<IDisposable>() != null, null, "Contract.Result<IDisposable>() != null");
			return null;
		}

		public static IDisposable Schedule<TState>(this IScheduler scheduler, TState state, DateTimeOffset dueTime, Action<TState, Action<TState, DateTimeOffset>> action)
		{
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Requires(action != null, null, "action != null");
			Contract.Ensures(Contract.Result<IDisposable>() != null, null, "Contract.Result<IDisposable>() != null");
			return null;
		}

		public static IDisposable Schedule<TState>(this IScheduler scheduler, TState state, TimeSpan dueTime, Action<TState, Action<TState, TimeSpan>> action)
		{
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Requires(action != null, null, "action != null");
			Contract.Ensures(Contract.Result<IDisposable>() != null, null, "Contract.Result<IDisposable>() != null");
			return null;
		}

#if !SILVERLIGHT
		public static IDisposable ScheduleAsync(this IScheduler scheduler, Func<IScheduler, CancellationToken, Task<IDisposable>> action)
		{
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Requires(action != null, null, "action != null");
			Contract.Ensures(Contract.Result<IDisposable>() != null, null, "Contract.Result<IDisposable>() != null");
			return null;
		}

		public static IDisposable ScheduleAsync(this IScheduler scheduler, DateTimeOffset dueTime, Func<IScheduler, CancellationToken, Task<IDisposable>> action)
		{
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Requires(action != null, null, "action != null");
			Contract.Ensures(Contract.Result<IDisposable>() != null, null, "Contract.Result<IDisposable>() != null");
			return null;
		}

		public static IDisposable ScheduleAsync(this IScheduler scheduler, TimeSpan dueTime, Func<IScheduler, CancellationToken, Task<IDisposable>> action)
		{
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Requires(action != null, null, "action != null");
			Contract.Ensures(Contract.Result<IDisposable>() != null, null, "Contract.Result<IDisposable>() != null");
			return null;
		}

		public static IDisposable ScheduleAsync<TState>(this IScheduler scheduler, TState state, Func<IScheduler, TState, CancellationToken, Task<IDisposable>> action)
		{
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Requires(action != null, null, "action != null");
			Contract.Ensures(Contract.Result<IDisposable>() != null, null, "Contract.Result<IDisposable>() != null");
			return null;
		}

		public static IDisposable ScheduleAsync<TState>(this IScheduler scheduler, TState state, DateTimeOffset dueTime, Func<IScheduler, TState, CancellationToken, Task<IDisposable>> action)
		{
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Requires(action != null, null, "action != null");
			Contract.Ensures(Contract.Result<IDisposable>() != null, null, "Contract.Result<IDisposable>() != null");
			return null;
		}

		public static IDisposable ScheduleAsync<TState>(this IScheduler scheduler, TState state, TimeSpan dueTime, Func<IScheduler, TState, CancellationToken, Task<IDisposable>> action)
		{
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Requires(action != null, null, "action != null");
			Contract.Ensures(Contract.Result<IDisposable>() != null, null, "Contract.Result<IDisposable>() != null");
			return null;
		}
#endif

		public static IDisposable ScheduleLongRunning(this ISchedulerLongRunning scheduler, Action<ICancelable> action)
		{
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Requires(action != null, null, "action != null");
			Contract.Ensures(Contract.Result<IDisposable>() != null, null, "Contract.Result<IDisposable>() != null");
			return null;
		}

#if !SILVERLIGHT
		public static SchedulerOperation Sleep(this IScheduler scheduler, DateTimeOffset dueTime)
		{
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<SchedulerOperation>() != null, null, "Contract.Result<SchedulerOperation>() != null");
			return null;
		}

		public static SchedulerOperation Sleep(this IScheduler scheduler, TimeSpan dueTime)
		{
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<SchedulerOperation>() != null, null, "Contract.Result<SchedulerOperation>() != null");
			return null;
		}

		public static SchedulerOperation Sleep(this IScheduler scheduler, DateTimeOffset dueTime, CancellationToken cancellationToken)
		{
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<SchedulerOperation>() != null, null, "Contract.Result<SchedulerOperation>() != null");
			return null;
		}

		public static SchedulerOperation Sleep(this IScheduler scheduler, TimeSpan dueTime, CancellationToken cancellationToken)
		{
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<SchedulerOperation>() != null, null, "Contract.Result<SchedulerOperation>() != null");
			return null;
		}

		public static SchedulerOperation Yield(this IScheduler scheduler)
		{
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<SchedulerOperation>() != null, null, "Contract.Result<SchedulerOperation>() != null");
			return null;
		}

		public static SchedulerOperation Yield(this IScheduler scheduler, CancellationToken cancellationToken)
		{
			Contract.Requires(scheduler != null, null, "scheduler != null");
			Contract.Ensures(Contract.Result<SchedulerOperation>() != null, null, "Contract.Result<SchedulerOperation>() != null");
			return null;
		}
#endif
	}
}